iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0

本次使用的組譯器為 nasm ,其他類似的組譯器還有 masm 與 yasm ,但我們這次不會使用,那環境建置好了就來個慣例的 HelloWorld

extern	_main
extern	_printf

section	.data
HelloWorld:	db	'HelloWorld',0

section	.text
_main:
	push	ebp
	mov	    ebp,esp
	push	HelloWorld
	call	_printf
	add 	esp,4
	pop	    ebp
	retn

將這段程式碼寫進文字編輯器,並在此程式碼的檔案路徑下打開 cmd 並輸入

nasm 檔案名稱.副檔名 -f win32
gcc 檔案名稱.obj -m32

若兩個指令都有成功執行,gcc 會預設輸出執行檔叫 a.exe 可在 gcc 的指令中使用 -o 參數來改變輸出的檔名。得到 a.exe 後便可在 cmd 中鍵入 a 或 a.exe 即可得到輸出為

HelloWorld

得到這行字即代表環境建置成功

我們可以先試著觀察一下這段程式碼,之後都會有主題做更詳盡的解釋,所以現階段我們先觀察就好。

extern	_main
extern	_printf

這兩行是宣告外部變數
宣告會使用到 _main 與 _printf 函式
可能會有人注意到為甚麼前面會加一個底線,這件事之後的主題會提到,所以先給一個關鍵字供各位查詢 Calling Convention

再來會注意到

section .data

section .text

這裡是將程式碼分成三段,存放程式碼的 .text 、存放已初始化變數的 .data 與存放為初始化變數的 .bss ,在 HelloWorld 中我們沒用到可變變數,所以沒有 .bss 。還有一個很相似的東西叫 segment ,可以去了解看看,據昨天 NASM Tutorial 的網站中,在 Memory Segment 分頁底下有寫到這裡的 section 與 segment 是同樣的作用,要注意這兩個東西大部分是同樣的概念,但若到別的地方就不一定了,例如 ELF 檔,可以到這篇文章稍微了解一下。

HelloWorld:	db	'HelloWorld',0

這行是 HelloWorld 變數的定義
這裡能分成三個部份看

HelloWorld:
			db
				'HelloWorld',0

HelloWorld : 稱為標籤在組語中若有跳轉的時候就需要標籤來作為標記,例如 goto 的用法,直接跳到標籤處。
db 是數據定義,定義該變數每單位要用多大的記憶體去分配。
'HelloWorld',0 是數據初始化的內容 ,後面有一個 0 目前我沒查出一個來源表示作用,但應該會是十進位 ASCII Code ,0 表示 NULL ,若要換行便換成 10 ,即 New Line 。

_main:
	push	ebp
	mov	    ebp,esp
	
	push	HelloWorld
	call	_printf
	add 	esp,4
	
	pop	    ebp
	retn

這一段便是主要執行的程式碼,相關的 OP Table 可以到這網站去參考。可以注意到正中央的那三行指令,我們先 push 了 HelloWorld 變數進 Stack 中,再去呼叫 printf ,最後再將 esp+4 ,關於 esp 與前後 4 行的解說我會放在後天,所以我們先專注在中間三行,如果請各位先用 C 寫出一支 HelloWorld ,再回來注意我們的組語

#include<stdio.h>
#include<stdlib.h>
int main(){
	printf("HelloWorld");
	return 0;
}

是不是覺得好像幾乎長的一模一樣 ?

今天先教輸出,接下來幾天我們先補一點理論知識再回來繼續補上輸入。


上一篇
Day1 環境簡介與建立
下一篇
Day3 語法&指令
系列文
絕對花心的30天組合語言13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Eason
iT邦新手 5 級 ‧ 2022-09-18 20:55:56

Hello bdeo

我要留言

立即登入留言